home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / docs / radius / examples / .tmpdes.php next >
PHP Script  |  2004-03-24  |  12KB  |  296 lines

  1. <?PHP
  2. /*The contents of this document are free for use by anyone for any purpose they choose.
  3. no warranty is implied, nor will one be honored.  The author assumes no liability for
  4. any consequences that may arise from the use of contents of this document.  Events not
  5. covered include but are not limited to: system crashes, system slowdown, system failure,
  6. fires, explosions, floods, earthquakes, boiling seas, intestinal inflammation, cold coffee,
  7. and total protonic inversion.
  8. Any questions, comments, or improvements are appreciated and can be directed to:
  9.  
  10. Tim Thorpe
  11. blushift@netins.net
  12. */
  13.  
  14. /*
  15. This script implements the 56-bit DES encryption algorithm,
  16. created from scratch based on interpretation of the original
  17. specification document.
  18.  
  19. des_encrypt_ecb("my key", "my text");
  20. and
  21. mcrypt_ecb (MCRYPT_DES, "my key", "my text", MCRYPT_ENCRYPT, str_pad("", 8, chr(0x00)));
  22. are functionally identical.
  23.  
  24. Because PHP is lacking in bitwise operators, this set of routines
  25. makes use of data that has been expanded so that a byte becomes an 8-byte string.
  26.  
  27. The script performs the transformations, and then condenses the data back to a usable form.
  28. Apologies for a lack of comments in the bulk of the functions.
  29. */////////////////////////////////////////////////////////////////////////////
  30.  
  31. function des_encrypt_ecb($key, $clearText) {
  32. //Function to implement Electronic Code Book encoding
  33. //I haven't had occasion to add any other methods or a decoder for that matter,
  34. //but all of the underlying functions were written to be universal to all encoding methods,
  35. //so adding other methods should be easy if you need them.
  36.  
  37.     if (strlen($key) < 7)
  38.         $key = str_pad(substr($key, 0, 7), 7, chr(0x00));  //We need 7 bytes for a key; no more, no less
  39.         
  40.     if (strlen($key) == 7) $key = des_add_parity($key);
  41.     
  42.     $keys = des_make_subkeys (des_bits_to_bytes ($key));  //Chew the key into the subkeys needed for DES
  43.     $blockCount = (int) (strlen($clearText) / 8);  //Figure out how many blocks of 8 bytes we need to encode
  44.     if (strlen ($clearText) % 8) {  //Check to see if there are any leftovers
  45.         $blockCount++;  //Add another block for them
  46.         $clearText = str_pad($clearText, $blockCount * 8, chr(0x00));  //Pad it out with zeroes
  47.     }
  48.     for ($i = 0; $i < $blockCount; $i++) {  //Cycle through the blocks
  49.         $clearBlock = substr($clearText, $i * 8, 8);  //Grab a block from the input
  50.         $cypherBlock = des_block_encode(des_bits_to_bytes ($clearBlock), $keys);  //Encrypt it
  51.         $cypherText .= des_bytes_to_bits ($cypherBlock);  //Convert the result back to a useful form
  52.     }
  53.     return ($cypherText);  //Cough it up
  54. }
  55.  
  56. function des_block_encode($clearText, $subKeys) {
  57.     $ip_table = array(58, 50, 42, 34, 26, 18, 10,  2,
  58.               60, 52, 44, 36, 28, 20, 12,  4,
  59.               62, 54, 46, 38, 30, 22, 14,  6,
  60.               64, 56, 48, 40, 32, 24, 16,  8,
  61.               57, 49, 41, 33, 25, 17,  9,  1,
  62.               59, 51, 43, 35, 27, 19, 11,  3,
  63.               61, 53, 45, 37, 29, 21, 13,  5,
  64.               63, 55, 47, 39, 31, 23, 15,  7);
  65.  
  66.     $ip1_table = array(40,  8, 48, 16, 56, 24, 64, 32,
  67.                39,  7, 47, 15, 55, 23, 63, 31,
  68.                38,  6, 46, 14, 54, 22, 62, 30,
  69.                37,  5, 45, 13, 53, 21, 61, 29,
  70.                36,  4, 44, 12, 52, 20, 60, 28,
  71.                35,  3, 43, 11, 51, 19, 59, 27,
  72.                34,  2, 42, 10, 50, 18, 58, 26,
  73.                33,  1, 41,  9, 49, 17, 57, 25);
  74.  
  75.     foreach ($ip_table as $bit) {
  76.         $ip .= $clearText[$bit - 1];
  77.     }
  78.     $l[0] = substr($ip, 0, 32);
  79.     $r[0] = substr($ip, 32);
  80.     for ($index = 1; $index <= 16; $index++) {
  81.         $l[$index] = $r[$index - 1];
  82.         $r[$index] = des_xor($l[$index - 1], des_transform($r[$index - 1], $subKeys[$index]));
  83.     }
  84.  
  85.     foreach ($ip1_table as $bit) {
  86.         $concat    = $r[16] . $l[16];
  87.         $cypherBlock .= $concat[$bit - 1];
  88.     }
  89.     return ($cypherBlock);
  90. }
  91.  
  92. function des_make_subkeys($key) {
  93.     $pc1 = array(57, 49, 41, 33, 25, 17,  9,
  94.               1, 58, 50, 42, 34, 26, 18,
  95.              10,  2, 59, 51, 43, 35, 27,
  96.              19, 11,  3, 60, 52, 44, 36,
  97.              63, 55, 47, 39, 31, 23, 15,
  98.               7, 62, 54, 46, 38, 30, 22,
  99.              14,  6, 61, 53, 45, 37, 29,
  100.              21, 13,  5, 28, 20, 12,  4);
  101.  
  102.     $pc2 = array(14, 17, 11, 24,  1,  5,
  103.               3, 28, 15,  6, 21, 10,
  104.              23, 19, 12,  4, 26,  8,
  105.              16,  7, 27, 20, 13,  2,
  106.              41, 52, 31, 37, 47, 55,
  107.              30, 40, 51, 45, 33, 48,
  108.              44, 49, 39, 56, 34, 53,
  109.              46, 42, 50, 36, 29, 32);
  110.  
  111.     $shifts = array(1, 1, 2, 2,
  112.             2, 2, 2, 2,
  113.             1, 2, 2, 2,
  114.             2, 2, 2, 1);
  115.     foreach ($pc1 as $bit) {
  116.         $k .= $key[$bit - 1];
  117.     }
  118.     $index = 0;
  119.     $c[$index] = substr($k, 0, 28);
  120.     $d[$index] = substr($k, 28);
  121.     unset ($k);
  122.     foreach ($shifts as $positions) {
  123.         $index++;
  124.         $c[$index] = des_rotate_left ($c[$index - 1], $positions);
  125.         $d[$index] = des_rotate_left ($d[$index - 1], $positions);
  126.     }
  127.     for ($i = 1; $i <= 16; $i++) {
  128.         foreach ($pc2 as $bit) {
  129.             $concat = $c[$i] . $d[$i];
  130.             $k[$i] .= $concat[$bit - 1];
  131.         }
  132.     }
  133.     return ($k);
  134. }
  135.  
  136. function des_transform($data, $key) {
  137.     $e_table = array(32,  1,  2,  3,  4,  5,
  138.               4,  5,  6,  7,  8,  9,
  139.               8,  9, 10, 11, 12, 13,
  140.              12, 13, 14, 15, 16, 17,
  141.              16, 17, 18, 19, 20, 21,
  142.              20, 21, 22, 23, 24, 25,
  143.              24, 25, 26, 27, 28, 29,
  144.              28, 29, 30, 31, 32,  1);
  145.  
  146.     $s = array(array(14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
  147.               0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
  148.               4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
  149.              15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13),
  150.            array(15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
  151.               3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
  152.               0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
  153.              13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9),
  154.            array(10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
  155.              13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
  156.              13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
  157.               1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12),
  158.            array( 7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
  159.              13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
  160.              10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
  161.               3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14),
  162.            array( 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
  163.              14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
  164.               4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
  165.              11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3),
  166.            array(12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
  167.              10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
  168.               9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
  169.               4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13),
  170.            array( 4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
  171.              13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
  172.               1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
  173.               6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12),
  174.            array(13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0,  12,  7,
  175.               1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
  176.               7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13,  15, 3,  5,  8,
  177.               2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11));
  178.  
  179.     $p_table = array(16,  7, 20, 21,
  180.                          29, 12, 28, 17,
  181.                           1, 15, 23, 26,
  182.                           5, 18, 31, 10,
  183.                           2,  8, 24, 14,
  184.                          32, 27,  3,  9,
  185.                          19, 13, 30,  6,
  186.                          22, 11,  4, 25);
  187.  
  188.     $nybbles = array(chr(0x00).chr(0x00).chr(0x00).chr(0x00), chr(0x00).chr(0x00).chr(0x00).chr(0x01),
  189.              chr(0x00).chr(0x00).chr(0x01).chr(0x00), chr(0x00).chr(0x00).chr(0x01).chr(0x01),
  190.              chr(0x00).chr(0x01).chr(0x00).chr(0x00), chr(0x00).chr(0x01).chr(0x00).chr(0x01),
  191.              chr(0x00).chr(0x01).chr(0x01).chr(0x00), chr(0x00).chr(0x01).chr(0x01).chr(0x01),
  192.              chr(0x01).chr(0x00).chr(0x00).chr(0x00), chr(0x01).chr(0x00).chr(0x00).chr(0x01),
  193.              chr(0x01).chr(0x00).chr(0x01).chr(0x00), chr(0x01).chr(0x00).chr(0x01).chr(0x01),
  194.              chr(0x01).chr(0x01).chr(0x00).chr(0x00), chr(0x01).chr(0x01).chr(0x00).chr(0x01),
  195.              chr(0x01).chr(0x01).chr(0x01).chr(0x00), chr(0x01).chr(0x01).chr(0x01).chr(0x01));
  196.  
  197.  
  198.     foreach ($e_table as $bit) {
  199.         $e .= $data[$bit - 1];
  200.     }
  201.     $ek = des_xor($e, $key);
  202.     for ($i = 0; $i < 8; $i++) {
  203.         $offset = $i * 6;
  204.         $sAddress = ord($ek[$offset]) * 0x20 +
  205.                 ord($ek[$offset + 1]) * 0x08 +
  206.                 ord($ek[$offset + 2]) * 0x04 +
  207.                 ord($ek[$offset + 3]) * 0x02 +
  208.                 ord($ek[$offset + 4]) +
  209.                 ord($ek[$offset + 5]) * 0x10;
  210.         $sResult .= $nybbles[$s[$i][$sAddress]];
  211.     }
  212.     foreach ($p_table as $bit) {
  213.         $p .= $sResult[$bit - 1];
  214.     }
  215.     return ($p);
  216. }
  217.  
  218. function des_bits_to_bytes($bitStream) {
  219.     for ($i = 0; $i < strlen($bitStream); $i++) {
  220.         $val = ord($bitStream[$i]);
  221.         if ($val & 0x80) {$byteStream .= chr(0x01);} else {$byteStream .= chr(0x00);}
  222.         if ($val & 0x40) {$byteStream .= chr(0x01);} else {$byteStream .= chr(0x00);}
  223.         if ($val & 0x20) {$byteStream .= chr(0x01);} else {$byteStream .= chr(0x00);}
  224.         if ($val & 0x10) {$byteStream .= chr(0x01);} else {$byteStream .= chr(0x00);}
  225.         if ($val & 0x08) {$byteStream .= chr(0x01);} else {$byteStream .= chr(0x00);}
  226.         if ($val & 0x04) {$byteStream .= chr(0x01);} else {$byteStream .= chr(0x00);}
  227.         if ($val & 0x02) {$byteStream .= chr(0x01);} else {$byteStream .= chr(0x00);}
  228.         if ($val & 0x01) {$byteStream .= chr(0x01);} else {$byteStream .= chr(0x00);}
  229.     }
  230.     return ($byteStream);
  231. }
  232.  
  233. function des_bytes_to_bits($byteStream) {
  234.     for ($i = 0; $i < (strlen($byteStream) / 8); $i++) {
  235.         $offset    = $i * 8;
  236.         $value = ord($byteStream[$offset]) * 0x80 +
  237.              ord($byteStream[$offset + 1]) * 0x40 +
  238.              ord($byteStream[$offset + 2]) * 0x20 +
  239.              ord($byteStream[$offset + 3]) * 0x10 +
  240.              ord($byteStream[$offset + 4]) * 0x08 +
  241.              ord($byteStream[$offset + 5]) * 0x04 +
  242.              ord($byteStream[$offset + 6]) * 0x02 +
  243.              ord($byteStream[$offset + 7]);
  244.         $bitStream .= chr($value);
  245.  
  246.     }
  247.     return ($bitStream);
  248. }
  249.  
  250. function des_rotate_left($input, $positions) {
  251.     return substr($input, $positions) . substr($input, 0, $positions);
  252. }
  253.  
  254. function des_xor($a, $b) {
  255.     for ($i = 0; $i < strlen($a); $i++) {
  256.         $xor .= $a[$i] ^ $b[$i];
  257.     }
  258.     return $xor;
  259. }
  260.  
  261. // DES helper function
  262. // input: 7-Bytes Key without parity
  263. // ouput: 8-Bytes Key with parity
  264. function des_add_parity($key) 
  265. {
  266.     static $odd_parity = array(
  267.         1,  1,  2,  2,  4,  4,  7,  7,  8,  8, 11, 11, 13, 13, 14, 14,
  268.         16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
  269.         32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
  270.         49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
  271.         64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
  272.         81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
  273.         97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
  274.         112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
  275.         128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
  276.         145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
  277.         161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
  278.         176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
  279.         193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
  280.         208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
  281.         224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
  282.         241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254);
  283.  
  284.     for ($i = 0; $i < strlen($key); $i++) {
  285.         $bin .= sprintf('%08s', decbin(ord($key{$i})));
  286.     }
  287.  
  288.     $str1 = explode('-', substr(chunk_split($bin, 7, '-'), 0, -1));
  289.     foreach($str1 as $s) {
  290.         $x .= sprintf('%02s', dechex($odd_parity[bindec($s . '0')]));
  291.     }
  292.  
  293.     return pack('H*', $x);
  294.  
  295. }
  296.